/**
 * Class: iCalEvent
 * 
 * @author Ryne Okimoto
 * 
 * Description: Creates a .ics file to be read by calendaring applications
 */

package nb314calendargui;

import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import javax.swing.JOptionPane;

public class testICalEvent {
    
    /* Data for date, date formatting, and timezone */
    private GregorianCalendar gCal = new GregorianCalendar();
    private SimpleDateFormat timeFormat = new SimpleDateFormat("HHmmss");
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
    public  TimeZone localeTZ = gCal.getTimeZone();
    
    /* Name of the timezone with daylight savings */
    private String DSTname;
    /* Name of the timezone without daylight savings */
    private String STname;
    /* The offset from UTC in the current timezone */
    private String UTCoffset;
    private String sTime;
    
    /* Data for properties that will be written to .ics file */
    private static final String VERSION = "VERSION:2.0\n";
    private static final String PRODID  = 
            "PRODID:-//ICS314 Congaree//Eventer 1.0//EN\n";
    private String date_start;
    private String date_end;
    private String classification;
    private String priority;
    private String location;
    private String resources;
    private String description;
    private String title;
    private String timestamp;
    private String filename;
    
    /* String containing all of the appended property data */
    private String content;
    
    /**
     * Default constructor
     * 
     * Sets all fields to null
     */
    public testICalEvent()
    {
        DSTname        = null;
        STname         = null;
        UTCoffset      = null;
        sTime          = null;
        date_start     = null;
        date_end       = null;
        classification = null;
        priority       = null;
        location       = null;
        resources      = null;
        description    = null;
        title          = null;
        timestamp      = null;
        filename       = null;
        content        = null;
    }
    
    /**
     * Constructor to initialize property fields
     * 
     * @param title The name of the event as a string
     * @param dStart The start date as a string
     * @param dEnd The end date as a string
     * @param tStart The start time as a string
     * @param tEnd The end time as a string
     * @param loc The location as a string
     * @param res The resources as a string
     * @param cl The classification as a string
     * @param priority The priority as a string
     * @param desc The description as a string
     */
    public testICalEvent(String title, String dStart, String dEnd, String tStart,
            String tEnd, String loc, String res, String cl, String priority,
            String desc)
    {
        /* Initialize fields with given parameters */
        setTitle(title);
        setFilename();
        setDate_start(dStart, tStart);
        setDate_end(dEnd, tEnd);
        setLocation(loc);
        setResources(res);
        setClassification(cl);
        setPriority(priority);
        setDescription(desc);
        setTimestamp();
        setTimezone();
    }
    
    /**
     * Method name: createFile
     * 
     * @param none
     * 
     * @return boolean
     * 
     * Description: Creates a .ics file with the initialized property fields
     */
    public boolean createFile()
    {
        BufferedWriter outputstream;
        
        /* Indicates successful .ics file creation */
        Boolean isCreated;
                
        try
        {
            outputstream = new BufferedWriter(new FileWriter(new File(filename)));
           
            content = 
                  "BEGIN:VCALENDAR\n" +
                  VERSION +
                  PRODID +
                    
                  /* Timezone component */
                  "BEGIN:VTIMEZONE\n" +
                  "TZID:" + localeTZ.getID() + "\n" +
                  "BEGIN:DAYLIGHT\n" +
                  "COMMENT:Info for daylight savings\n" +
                  "TZOFFSETFROM:" +  UTCoffset +
                  "DTSTART:" + "19330430T020000\n" +
                  "TZNAME:" +  DSTname +
                  "TZOFFSETTO:" + sTime +
                  "RDATE:" + "19330430T020000\n" +
                  "END:DAYLIGHT\n" +
                  "BEGIN:STANDARD\n" +
                  "COMMENT:Info for standard time\n" +
                  "TZOFFSETFROM:" + UTCoffset +
                  "DTSTART:" + "19470608T020000\n" +
                  "TZNAME:" + STname +
                  "TZOFFSETTO:" + sTime +
                  "RDATE:" + "19470608T020000\n" +
                  "END:STANDARD\n" +
                  "END:VTIMEZONE\n" +
                    
                  /* Event component */
                  // some data commented out for debugging
                  "BEGIN:VEVENT\n" +
                  "COMMENT:Event details found below\n" +
                  // added fields for debugging and testing, comment out the set time
                  "CREATED:" + "20120808"/* dateFormat.format(gCal.getTime()) + */ +
                      "T" + "120000" + /* timeFormat.format(gCal.getTime()) + */ "Z\n" +
                  "UID:" + "DefaultUser" + "\n" + // Add UID here
                  classification +
                  priority +
                  "DTSTART;TZID=" + localeTZ.getID() + ":" + date_start +
                  "DTEND;TZID=" + localeTZ.getID() + ":" + date_end + 
                  
                  /* Event is marked as busy by default */
                  /* User cannot change when creating .ics file */
                  /* User can change from busy to free after importing */
                  "TRANSP:OPAQUE\n" +
                  title +
                  location +
                  resources +
                  /* timestamp + */
                  description +
                  "END:VEVENT\n" +
                  "END:VCALENDAR\n";
            
            outputstream.write(content);
            outputstream.close();
            
            isCreated = true;
        }
        catch(IOException ie)
        {
            JOptionPane.showMessageDialog(null, "Error creating file");
            isCreated = false;
        }
        
        return isCreated;
    }
    
    /**
     * Method name: setTitle
     * 
     * @param t The title of the event as a string
     * 
     * @return none
     * 
     * Description: Initializes the SUMMARY property
     */
    private void setTitle(String t)
    {
        this.title = "SUMMARY:" + t + "\n";
    }
    
    /**
     * Method name: setFilename
     * 
     * @param none
     * 
     * @return none
     * 
     * Description: Generates the filename for the .ics file
     *              Filename format is "Eventer-yyyymmdd-hhmmss.ics"
     */
    private void setFilename()
    {
    	// comment this when trying to test that filename is saved properly
        /* this.filename =  "Eventer-" + dateFormat.format(gCal.getTime()) + "-" + 
                timeFormat.format(gCal.getTime()) + ".ics"; */
        
        // for debug purposes please use this for testing, comment above
        // when this is in use
        this.filename = "test_Filename.ics";
    }
    
    /**
     * Method name: setDate_start
     * 
     * @param date The formatted date as a string
     * @param time The formatted time as a string
     * 
     * @return none
     * 
     * Description: Initializes the DTSTART property for the event
     */
    private void setDate_start(String date, String time)
    {
        this.date_start = date + "T" + time + "\n";
    }
    
    /**
     * Method name: setDate_end
     * 
     * @param date The formatted date as a string
     * @param time The formatted time as a string
     * 
     * @return none
     * 
     * Description: Initializes the DTEND property for the event
     */
    private void setDate_end(String date, String time)
    {
        this.date_end = date + "T" + time +"\n";
    }
    
    /**
     * Method name: setLocation
     * 
     * @param l The location of the event as a string
     * @return none
     * 
     * Description: Initializes the LOCATION property for the event
     */
    private void setLocation(String l)
    {
        this.location = "LOCATION:" + l + "\n";
    }
    
    /**
     * Method name: setResources
     * 
     * @param r The resources for the event as a string
     * @return none
     * 
     * Description: Initializes the RESOURCES property for the event
     */
    private void setResources(String r)
    {
        this.resources = "RESOURCES:" + r + "\n";
    }
    
    /**
     * Method name: setClassification
     * 
     * @param c The privacy level of the event as a string
     * @return none
     * 
     * Description: Initializes the CLASS property for the event
     */
    private void setClassification(String c)
    {
        this.classification = "CLASS:" + c +"\n";
    }
    
    /**
     * Method name: setPriority
     * 
     * @param p The relative priority of the event as a string
     * @return none
     * 
     * Description: Initializes the PRIORITY property for the event
     */
    private void setPriority(String p)
    {
        /*
         * The priority is a integer value 0-9 converted to a string
         */
        this.priority = "PRIORITY:" + p +"\n";
    }
    
    /**
     * Method name: setDescription
     * 
     * @param d The description of the event as a string
     * @return none
     * 
     * Description: Initializes the DESCRIPTION property for the event
     */
    private void setDescription(String d)
    {   
        /*
         * Replace all newlines with "\n"
         * The string must contain "\n" to preserve formatting
         * and for the .ics file to be read properly
         * 
         * Then append the description to the property name
         */
        d = d.replaceAll("\n", "\\\\n");
        this.description = "DESCRIPTION:" + d + "\n";
    } 
    
    /**
     * Method name: setTimestamp
     * 
     * @param none
     * @return none
     * 
     * Description: Initializes the DTSTAMP property for the event
     */
    private void setTimestamp()
    {
        /*
         * Gets the current date and time used to stamp the .ics file
         */
        this.timestamp = "DTSTAMP:" + dateFormat.format(gCal.getTime()) +
                         "T" + timeFormat.format(gCal.getTime()) + "Z" + "\n";
    }
    
    /**
     * Method name: setTimezone
     * 
     * @param none
     * @return none
     * 
     * Description: Function that gets and sets the timezone name,
     *              name of the timezone in daylight savings,
     *              name of the timezone in standard time,
     *              UTC offset of the timezone,
     *              UTC offset of the timezone in DST
     */
    private void setTimezone()
    {
        int DST = gCal.get(Calendar.DST_OFFSET);
        
        // Get the name of the timezone that the user is in
        // based on the timezone of the user's computer
        
        /* Name of the timezone in standard and daylight savings */
        DSTname = localeTZ.getDisplayName(true, TimeZone.LONG) + "\n";
        STname = localeTZ.getDisplayName(false, TimeZone.LONG) + "\n";
        
        /* Get the UTC offset of the current timezone in ms */
        int offset = localeTZ.getRawOffset();  
        
        /* 
         * Convert the UTC offset to (+/-)hhmm format for 
         * standard and daylight savings in the current timezone
         */
        UTCoffset = String.format("%s%02d%02d\n", offset >= 0 ? "+" : "", 
                offset / 3600000, (offset / 60000) % 60);
        
        sTime = String.format("%s%02d%02d\n", (offset + DST) >= 0 ? "+" : "", 
                (offset + DST) / 3600000, ((offset + DST) / 60000) % 60);
    }
    
    // TESTING METHODS BELOW
    /**
     * Method name: getAllValues
     * 
     * Method is used for debug purposes ONLY, returns String array containing all data
     * in the order as listed above
     */
    public String[] getAllValues() {
    	String[] allData = new String[15];

    	// Order in which data is initialized in default constructor
    	allData[0]  = this.DSTname;
    	allData[1]  = this.STname;
    	allData[2]  = this.UTCoffset;
    	allData[3]  = this.sTime;
    	allData[4]  = this.date_start;
    	allData[5]  = this.date_end;
    	allData[6]  = this.classification;
    	allData[7]  = this.priority;
    	allData[8]  = this.location;
    	allData[9]  = this.resources;
    	allData[10] = this.description;
    	allData[11] = this.title;
    	allData[12] = this.timestamp;
    	allData[13] = this.filename;
    	allData[14] = this.content;
  
    	return allData;
    }
}
